import React, { useContext, useState } from 'react';
import {Button, Col, Form, Row, message, Badge, Tooltip, notification} from 'antd';
import { SerialContext } from '../context/SerialContext';
import EventBusManager from '../utils/eventBusManager';
import SerialPortValidator from '../models/validators/SerialPortValidator';
import { SerialService } from '../services/SerialService';
import { handleUpError, getSerialErrorMessage } from '../utils/errorHandler';
import SerialDeviceSelectView from '../views/SerialDeviceSelectView';
import SerialBaudRateSelectView from '../views/SerialBaudRateSelectView';
import SerialParityView from '../views/SerialParityView';
import SerialStopBitsView from '../views/SerialStopBitsView';
import SerialDataBitsView from '../views/SerialDataBitsView';
import SerialFlowControlView from '../views/SerialFlowControlView';
import SerialTimeOutView from '../views/SerialTimeOutView';
import type {
  OpenSerialRequest,
  Parity,
  FlowControl,
} from '../models/up_request';
import './SerialConnectComponent.css';
import {useSerialFormStore} from "../stores/serialConnectStore";
import {useDebouncedClickWithMessage} from "../utils/debouncedClick";

interface Props {
  showSearchButton: boolean;
  onSearchStartUp: () => void;
}

const SerialConnectComponent: React.FC<Props> = ({
  showSearchButton,
  onSearchStartUp,
}) => {
  const ctx = useContext(SerialContext);
  const eventBus = EventBusManager.getInstance();
  if (!ctx) return null;
  const { serialState, setSerialState, globalModel, setGlobalModel } = ctx;
  const { formData, setFormData } = useSerialFormStore();
  const [form] = Form.useForm();
  const [expanded, setExpanded] = useState(false);

  // 统一类型安全的 handleChange
  const handleChange = <K extends keyof OpenSerialRequest>(
    key: K,
    value: OpenSerialRequest[K]
  ) => {
    const newFormData = { ...formData, [key]: value };
    setFormData(newFormData);
  };

  const openSerialPort = async () => {
    if (serialState.isSerialOpen) return message.error('串口已经打开！');
    if (serialState.isSerialSearch) return message.error('请先停止搜索！');
    if (serialState.isSerialUpgrade) return message.error('请先停止升级！');
    const validation = SerialPortValidator.validateForm(formData);
    if (!validation.isValid) {
      return;
    }
    try {
      const data = await SerialService.openSerial(formData);
      setGlobalModel((prev) => ({ ...prev, global_serial_id: data }));
      setSerialState((prev) => ({ ...prev, isSerialOpen: true }));
      eventBus.emit('global_serial_id', data);
      message.success('串口打开成功！');
    } catch (err) {
      handleUpError(err);

      const { isSerialError, errorMessage } = getSerialErrorMessage(err);
      if (isSerialError) {
        notification.error({
          message: '串口打开失败！',
          description: errorMessage,
          duration: 3,
        });
      }
    }
  };

  const closeSerialPort = async () => {
    try {
      await SerialService.closeSerial(globalModel.global_serial_id);
      setSerialState((prev) => ({ ...prev, isSerialOpen: false }));
      setGlobalModel((prev) => ({ ...prev, global_serial_id: '' }));
      eventBus.emit('global_serial_id', '');
      message.success('串口关闭成功！');
    } catch (err) {
      handleUpError(err);
      message.error('串口关闭失败！');
    }
  };

  const startSearchCommand = async () => {
    if (serialState.isSerialOpen) return message.error('请先关闭串口！');
    if (serialState.isSerialSearch) return message.error('搜索已经开始！');
    try {
      message.success('搜索已开始');
      onSearchStartUp();
      setSerialState((prev) => ({ ...prev, isSerialSearch: true }));
      await window.electron.ipcRenderer.invoke(
        'start-search',
        formData.device,
        [formData.baudrate]
      );
    } catch (err) {
      setSerialState((prev) => ({ ...prev, isSerialSearch: false }));
      handleUpError(err);
      message.error('搜索失败');
    }
  };

  const stopSearchCommand = async () => {
    try {
      await window.electron.ipcRenderer.invoke('stop-search');
      setSerialState((prev) => ({ ...prev, isSerialSearch: false }));
      message.success('搜索已停止');
    } catch (err) {
      setSerialState((prev) => ({ ...prev, isSerialSearch: true }));
      handleUpError(err);
      message.error('停止搜索失败');
    }
  };

  // 按钮防抖
  const { debouncedAction: debouncedStart, isLoading: isStarting } =
      useDebouncedClickWithMessage(startSearchCommand, 1000, '搜索太频繁了，请稍等！');
  const { debouncedAction: debouncedStop, isLoading: isStopping } =
      useDebouncedClickWithMessage(stopSearchCommand, 1000, '停止太频繁了，请稍等！');

  return (
    <Form form={form} layout="vertical" className="serial-form">
      <Row gutter={20} align="middle">
        <Col span={6}>
          <Form.Item label="设备" style={{ marginBottom: 0 }}>
            <SerialDeviceSelectView
              value={formData.device}
              onChange={(val) => handleChange('device', val)}
            />
          </Form.Item>
        </Col>
        <Col span={6}>
          <Form.Item label="波特率" style={{ marginBottom: 0 }}>
            <SerialBaudRateSelectView
              value={formData.baudrate}
              onChange={(val) => handleChange('baudrate', val)}
            />
          </Form.Item>
        </Col>
        <Col span={12}>
          <Row
            justify="end"
            gutter={12}
            align="middle"
            className="serial-button-group"
          >
            <Col>
              <Tooltip
                title={serialState.isSerialOpen ? '串口已打开' : '串口已关闭'}
              >
                <Badge
                  color={serialState.isSerialOpen ? 'red' : 'gray'}
                  status="processing"
                  text=""
                />
              </Tooltip>
            </Col>
            {showSearchButton && (
              <>
                <Col>
                  <Button
                      type={!serialState.isSerialSearch ? "primary" : undefined}
                      onClick={serialState.isSerialSearch ? debouncedStop : debouncedStart}
                  >
                    {serialState.isSerialSearch ? "停止" : "搜索"}
                  </Button>
                </Col>
              </>
            )}
            <Col>
              <Button
                  type={serialState.isSerialOpen ? "default" : "primary"}
                  onClick={serialState.isSerialOpen ? closeSerialPort : openSerialPort}
              >
                {serialState.isSerialOpen ? "断开" : "连接"}
              </Button>
            </Col>
          </Row>
        </Col>
      </Row>

      {expanded && (
        <>
          <Row gutter={20}>
            <Col span={8}>
              <Form.Item label="校验位">
                <SerialParityView
                  value={formData.parity}
                  onChange={(val) => handleChange('parity', val as Parity)}
                />
              </Form.Item>
            </Col>
            <Col span={8}>
              <Form.Item label="停止位">
                <SerialStopBitsView
                  value={String(formData.stopbits)}
                  onChange={(val) => handleChange('stopbits', Number(val))}
                />
              </Form.Item>
            </Col>
            <Col span={8}>
              <Form.Item label="数据位">
                <SerialDataBitsView
                  value={formData.databits}
                  onChange={(val) => handleChange('databits', val)}
                />
              </Form.Item>
            </Col>
          </Row>
          <Row gutter={20}>
            <Col span={8}>
              <Form.Item label="流控制">
                <SerialFlowControlView
                  value={formData.flowcontrol}
                  onChange={(val) =>
                    handleChange('flowcontrol', val as FlowControl)
                  }
                />
              </Form.Item>
            </Col>
            <Col span={8}>
              <Form.Item label="超时时间（秒）">
                <SerialTimeOutView
                  value={formData.timeout}
                  onChange={(val) => handleChange('timeout', val ?? 10)}
                />
              </Form.Item>
            </Col>
          </Row>
        </>
      )}
    </Form>
  );
};

export default SerialConnectComponent;
